<?php
//关于缩略图的相关的一些配置和算法
namespace Kuoqi\FileDriver;

/**
 * 图片缩略图的内容
 * Class ImageThumb
 * @package Kuoqi\FileDriver
 */
class ImageThumb{
    //W:width,H:height,
    //f:fixed:固定的大小
    //a:auto:自动的属性//stretching
    //scale:按照比例自动拉伸
    //位置默认左上角
    //Position-c：centor,L,左侧，T:上侧，R:右侧,B:底部,LT,RT,BR,BL,C
    const MODE_WFHFPLT = 0;//跟随系统的默认方式
    const MODE_WAHF = 1;//宽度自动高度不变的方案
    const MODE_WFHA = 2;//宽度固定高度自动的方案
    const MODE_MAXAUTO = 3;//指定最大的一边，另外一边自动适应
    const MODE_WAHAPC = 4;//裁剪，使用自动缩放保持图片不变形的铺满裁剪
    const MODE_LIST = array(
        self::MODE_WFHFPLT,//width fixed height fixed position left and top
        self::MODE_WAHF,// width auto height fixed position unset
        self::MODE_WFHA,//widtt fixed height auto position unset
        self::MODE_MAXAUTO,//one side is max-fixed and other is auto
        self::MODE_WAHAPC,//裁剪，使用自动缩放保持图片不变形的铺满裁剪
    );
    /**
     * @var int 模型
     */
    protected $_mode = 0;
    protected $_is_valied = true;
    protected $_errmsg = '';
    /**
     * @var null 数据源
     */
    protected $_source = null;//源对象
    protected $_thumb = null;//缩略图对象
    protected $_w = 0;//源的w
    protected $_h = 0;//源的h
    protected $_cropx = 0;//复制源的x
    protected $_cropy = 0;//复制源的y
    protected $_cropw = 0;//复制源的宽度
    protected $_croph = 0;//复制源的高度
    protected $_focusw = 0;//目标宽度
    protected $_focush = 0;//目标高度
    //protected $_focusx = 0;//裁剪的x
    //protected $_foucsy = 0;//裁剪的y

    /**
     * 初始化
     * ImageThumb constructor.
     */
    public function __construct()
    {
        $this->_mode = self::MODE_WFHFPLT;
    }
    /**
     * 根据url链接获取文件源
     * createby kuoqi at 2022/9/21 9:51
     */
    public function inputWithWeb($url){
        $this->_source = imagecreatefromstring(file_get_contents($url));
        $this->initSourceSize();//初始化源的相关信息
    }
    /**
     * 根据路径获取文件源
     * createby kuoqi at 2022/9/21 10:38
     * @param $path
     */
    public function inputWithPath($path){
        $this->_source = imagecreatefromstring(file_get_contents($path));
        $this->initSourceSize();//初始化源的相关信息
    }
    /**
     * 根据二进制流获取文件源
     * createby kuoqi at 2022/9/21 10:38
     * @param $stream
     */
    public function inputWithStream($stream){
        $this->_source = imagecreatefromstring($stream);
        $this->initSourceSize();//初始化源的相关信息
    }
    /**
     * 根据对象信息获取文件源
     * createby kuoqi at 2022/9/21 14:29
     * @param $source
     */
    public function inputWithSource($source){
        $this->_source = $source;
        $this->initSourceSize();//初始化源的相关信息
    }
    //根据base64获取
    public function inputWithBase64($stream){
        $code = strpos($stream,',');
        if($code===false){
            throw new \Kuoqi\Error('请输入base64的数据信息');
        }
        $stream = substr($stream,$code + 1);
        $this->_source = imagecreatefromstring(base64_decode($stream));
        $this->initSourceSize();//初始化源的相关信息
    }
    /**
     * 初始化源的宽高信息
     * createby kuoqi at 2022/9/21 11:22
     */
    private function initSourceSize(){
        $this->_w = imagesx($this->_source);
        $this->_h = imagesy($this->_source);
    }
    /**
     * 获取mode
     * createby kuoqi at 2022/9/21 11:27
     * @param $mode
     */
    public function mode($mode){
        $this->_mode = $mode;
    }
    //设置大小
    public function setSize($w,$h){
        $this->_focusw = $w;
        $this->_focush = $h;
    }

    //初始化缩略图
    public function initThumb(){
        switch($this->_mode){
            case self::MODE_WAHF:$this->initParamWithWAHF();break;
            case self::MODE_WFHA:$this->initParamWithWFHA();break;
            case self::MODE_MAXAUTO:$this->initParamWithMAXAUTO();break;
            case self::MODE_WAHAPC:$this->initParamWithWAHAPC();break;
            default:$this->initParamWithWFHFPLT();
        }
    }
    //-width fixed height fixed position left and top
    private function initParamWithWFHFPLT(){
        if(!$this->_focusw * $this->_focush){
            $this->_errmsg = '该模式[MODE_WFHFPLT]下请传入目标宽高';
            return $this->_is_valied = false;
        }
        //不进行缩放的展示图片内容
        $this->_cropx = 0;
        $this->_cropy = 0;
        $this->_cropw = $this->_focusw;
        $this->_croph = $this->_focush;
    }

    /**
     * createby kuoqi at 2022/10/27 8:28 裁剪，使用自动缩放保持图片不变形的铺满裁剪
     * @return bool
     */
    private function initParamWithWAHAPC(){
        if(!$this->_focusw * $this->_focush){
            $this->_errmsg = '该模式[MODE_WFHFPLT]下请传入目标宽高';
            return $this->_is_valied = false;
        }
        //不进行缩放的展示图片内容
        $this->_cropx = 0;
        $this->_cropy = 0;
        $rate = $this->_focusw / $this->_focush;
        $orate = $this->_w / $this->_h;
        if($orate>$rate){
            $this->_croph = $this->_h;
            $this->_cropw = $this->_croph * $rate;
        }else{
            $this->_cropw = $this->_w;
            $this->_croph = $this->_cropw / $rate;
        }
    }
    //宽度自动适配高度固定的模式
    private function initParamWithWAHF(){
        if(!$this->_focush){
            $this->_errmsg = '该模式[MODE_WAHF]下请传入目标高度';
            return $this->_is_valied = false;
        }
        $this->_cropx = 0;
        $this->_cropy = 0;
        $this->_cropw = $this->_w;
        $this->_croph = $this->_h;
        $this->_focusw = $this->_w / $this->_h * $this->_focush;
    }
    //高度自动适配，宽度为固定值
    private function initParamWithWFHA(){
        if(!$this->_focusw){
            $this->_errmsg = '该模式[MODE_WFHA]下请传入目标宽度';
            return $this->_is_valied = false;
        }
        $this->_cropx = 0;
        $this->_cropy = 0;
        $this->_cropw = $this->_w;
        $this->_croph = $this->_h;
        //$this->_focush = $this->_focush;
        $this->_focush = $this->_focusw / $this->_w * $this->_h;
    }

    //长边为最长，短边自动适应
    private function initParamWithMAXAUTO(){
        if(!$this->_focusw * $this->_focush){
            $this->_errmsg = '该模式[MODE_WFHFPLT]下请传入目标宽高';
            return $this->_is_valied = false;
        }
        //不进行缩放的展示图片内容
        $this->_cropx = 0;
        $this->_cropy = 0;
        $this->_cropw = $this->_w;
        $this->_croph = $this->_h;
        $rotatesrc = $this->_w / $this->_h;
        $rotatedst = $this->_focusw / $this->_focush;
        if($rotatesrc / $rotatedst > 1){
            //原图宽高比过大
            //新图片宽度不变
            //$this->_focusw = $this->_focusw;
            //高度变小
            $this->_focush = $this->_focusw / $this->_w * $this->_h;
        }else{
            //原图宽高比过小
            //新图片高度不变，宽度变小
            $this->_focusw = $this->_w / $this->_h * $this->_focush;
        }
    }

    //根据当前配置冲刷对象信息
    //bool imagecopyresized( resource $dst_image, resource $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_w, int $dst_h, int $src_w, int $src_h)
    public function flushThumb(){
        if($this->_focusw * $this->_focush ==0){ throw new \Kuoqi\Error("请配置缩略图的模式和宽高进行使用");}
        $this->_thumb =  imagecreatetruecolor($this->_focusw,$this->_focush);
        if(!@imagecopyresized($this->_thumb,$this->_source
            ,0,0
            ,$this->_cropx ,$this->_cropy
            ,$this->_focusw,$this->_focush
            ,$this->_cropw,$this->_croph
        )){
            $this->_errmsg = '该模式[MODE_WFHFPLT]下请传入目标宽高';
            return $this->_is_valied = false;
        }

        return true;
    }

    public function toThumb($format = 'S',$ext = ''){
        $this->initThumb();//初始化相关参数的信息
        $this->flushThumb();//根据当前配置冲刷对象信息
        if($format=='F'){
            return $this->toFile($ext);
        }else{
            return $this->toStream();
        }

    }
    //以文件的形式返回
    public function toFile($file){
        $file = \Kuoqi\Route::str2rootpath($file);
        is_dir(dirname($file))||@mkdir(dirname($file),777,true);
        imagepng($this->_thumb,$file);
        imagedestroy($this->_thumb);
        return $file;
    }
    /**
     * 返回内容区域的信息
     * createby kuoqi at 2022/10/1 10:53
     * @return string
     */
    public function toContent(){
        ob_start();
        imagepng($this->_thumb);
        imagedestroy($this->_thumb);
        return ob_get_clean();//获取缓冲区内容
    }
    //转换为jpg
    public function toJpeg($fileapath = ''){
        if($fileapath){
            $file = \Kuoqi\Route::str2rootpath($fileapath);
            is_dir(dirname($fileapath))||@mkdir(dirname($fileapath),777,true);
            imagejpeg($this->_thumb,$file);
            imagedestroy($this->_thumb);
            return $file;
        }else{
            ob_end_clean();
            header('content-type:image/jpeg');
            imagejpeg($this->_thumb);
            imagedestroy($this->_thumb);
            die();
        }
    }
    //转换为png
    public function toPng(){
        ob_end_clean();
        header('content-type:image/png');
        imagepng($this->_thumb);
        imagedestroy($this->_thumb);
        die();
    }

    public function toStream(){
        ob_start();
        imagepng($this->_thumb);
        imagedestroy($this->_thumb);
        $img = ob_get_clean();//获取缓冲区内容
        $imgInfo = 'data:png;base64,'.chunk_split(base64_encode($img));//转base64
        return $imgInfo;
    }

    /**
     * 输出一个base64字符串
     * @return string|void
     * User kuoqi
     * Datetime 2022/5/12 14:22
     * Remark
     */
    public function toBase64(){
        ob_clean();
        ob_start();
        imagepng($this->_thumb);
        imagedestroy($this->_thumb);
        $img = ob_get_clean();//获取缓冲区内容
        $imgInfo = 'data:png;base64,'.base64_encode($img);//转base64
        return $imgInfo;
    }
}